import sys

from PyQt5.QtCore import Qt, QCoreApplication, QRectF, QEvent, QPoint, QPointF
from PyQt5.QtGui import QKeySequence, QPainter, QPixmap, QPen, QFont, QResizeEvent, QBrush, QTouchEvent, QMouseEvent
from PyQt5.QtWidgets import QGraphicsView, QShortcut, QGraphicsScene, QGraphicsPixmapItem, QGraphicsSimpleTextItem, \
    QGraphicsItem, QApplication, QGraphicsRectItem, QGraphicsPathItem, QGraphicsLineItem, QMessageBox

import resources.resource_rc


class TpDrawLineWindow(QGraphicsView):
    rectangles = set()
    coordinate = "(0, 0)"
    square_w = 80
    tip = "请使用一根手指触摸"
    screenLength = 0
    screenWidth = 0
    totalSet = set()
    doneSet = set()

    def __init__(self, parent=None):
        super().__init__(parent)
        # 引入公共程序
        from utils.common import commonProgram
        # 引入配置文件
        self.myConfig = commonProgram.EnableConfigHandler()
        print('TpDrawLineWindow get config Version', self.myConfig.version)
        commonProgram.UpdateScreenResolution()
        self.square_w = int(self.square_w / self.myConfig.screenRatio)

        # 快捷键
        self.screenStatus = 'Normal'
        screenShortcut = QShortcut(QKeySequence(Qt.Key_F11), self)
        screenShortcut.activated.connect(self.WindowSizeFun)
        self.setToolTip('全屏与退出全屏：\n               F11')

        # print('self.totalSet', len(self.totalSet))
        self.WindowSizeFun()

    def __initWidget(self):
        """ 初始化小部件 """
        # self.resize(int(self.screenLength/2), int(self.screenWidth/2))
        # 隐藏滚动条
        # self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        # self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        # 以鼠标所在位置为锚点进行缩放
        self.setTransformationAnchor(self.AnchorUnderMouse)

        # 平滑缩放
        # self.pixmapItem.setTransformationMode(Qt.SmoothTransformation)
        self.setRenderHints(QPainter.Antialiasing |
                            QPainter.SmoothPixmapTransform)

        # 设置场景
        # self.graphicsScene.addItem(self.pixmapItem)
        # 创建场景
        self.graphicsScene = QGraphicsScene()
        self.graphicsScene.clearSelection()  # 【清除选择】
        self.setScene(self.graphicsScene)
        self.setAlignment(Qt.AlignLeft | Qt.AlignTop)
        self.setSceneRect(0, 0, self.screenLength, self.screenWidth)  # fix scene size 500 500
        self.setRenderHint(QPainter.Antialiasing)  ##设置视图的抗锯齿渲染模式。

        # print(self.sceneRect())
        # print(self.rect())
        # 通过图标
        self.pixmapPass = QGraphicsPixmapItem(QPixmap(':/icons/icons/pass.png'))
        self.pixmapPass.setScale(0.5)
        self.pixmapPass.setZValue(1)
        self.pixmapPass.setPos(self.screenLength / 2, self.screenWidth / 2 - 100)
        self.pixmapPass.setVisible(False)
        self.graphicsScene.addItem(self.pixmapPass)

        # 提示文字
        self.coordinateText = QGraphicsSimpleTextItem(self.coordinate)
        self.coordinateText.setPen(QPen(Qt.red))
        self.coordinateText.setPos(self.screenLength * 6 / 13, self.screenWidth * 7 / 9)
        self.coordinateText.setFlags(QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsMovable)
        self.coordinateText.setZValue(1)
        self.coordinateText.setFont(QFont('SimSun', 30))
        self.graphicsScene.addItem(self.coordinateText)

        # 坐标文字
        tipText = QGraphicsSimpleTextItem(self.tip)
        tipText.setPen(QPen(Qt.red))
        tipText.setPos(self.screenLength * 4 / 9, self.screenWidth / 8)
        tipText.setFlags(QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsMovable)
        # tipText.setScale(1.5)
        tipText.setFont(QFont('SimSun', 30))
        self.graphicsScene.addItem(tipText)

        # 画对脚线
        # line1 = QGraphicsLineItem(0, 0, self.screenLength, self.screenWidth)
        # line1.setPen(QPen(Qt.gray))
        # line2 = QGraphicsLineItem(0, self.screenWidth, self.screenLength, 0)
        # line2.setPen(QPen(Qt.gray))
        # rect.setBrush(QBrush(Qt.blue))
        # 加入场景
        # self.graphicsScene.addItem(line1)
        # self.graphicsScene.addItem(line2)
        # self.show()

    def WindowSizeFun(self):
        # print(toStatus)
        if self.screenStatus == 'Normal':
            self.showFullScreen()
            self.screenStatus = 'FullScreen'
        else:
            self.showNormal()
            self.screenStatus = 'Normal'

    def resizeEvent(self, event):  # real signature unknown; restored from __doc__
        """ resizeEvent(self, QResizeEvent) """
        screen_w = event.size().width()
        screen_h = event.size().height()
        if screen_w == 0 or screen_h == 0:
            return
        if self.screenLength == screen_w and self.screenWidth == screen_h:
            return
        self.rectangles.clear()
        self.screenLength = screen_w
        self.screenWidth = screen_h
        # print('w:' + str(screen_w) + ", h:" + str(screen_h))
        n = int(screen_w / self.square_w) - 2
        w = int(screen_w / (n + 2))
        h = int((2 * screen_h) / (n + 5))
        left = 0
        top = 0

        horizontal_limit = int(screen_w - w * 3 / 2)
        horizontal_delta = w
        vertical_delta = h
        # first row
        while left < horizontal_limit:
            self.rectangles.add(f"{left}, {top}, {w}, {h}")
            left += horizontal_delta
        # the last rectangle in the first row
        last_rect_w = screen_w - left
        last_rect_left = left
        self.rectangles.add(f"{last_rect_left}, {top}, {last_rect_w}, {h}")
        # first column
        vertical_limit = int(screen_h - h * 3 / 2)
        left = 0
        top = vertical_delta
        while top < vertical_limit:
            self.rectangles.add(f"{left}, {top}, {w}, {h}")
            top += vertical_delta
        # last column
        last_rect_top = top
        last_rect_h = screen_h - top
        top = vertical_delta
        while top < vertical_limit:
            self.rectangles.add(f"{last_rect_left}, {top}, {last_rect_w}, {h}")
            top += vertical_delta
        # last row
        left = 0
        while left < horizontal_limit:
            self.rectangles.add(f"{left}, {last_rect_top}, {w}, {last_rect_h}")
            left += horizontal_delta
        # last square on the right bottom conner
        self.rectangles.add(f"{left}, {last_rect_top}, {last_rect_w}, {last_rect_h}")
        # diagonal rectangle
        left = horizontal_delta
        top = vertical_delta
        # first rectangle
        self.rectangles.add(f"{left}, {top}, {w}, {h}")
        # middle rectangle
        left = int(horizontal_delta * 2)
        dia_top = vertical_delta + int(((screen_h - h - last_rect_h) - (n + 1) * h / 2) / 2 + h / 2)
        top = dia_top
        while left < horizontal_limit - vertical_delta:
            self.rectangles.add(f"{left}, {top}, {w}, {h}")
            left += horizontal_delta
            top += int(h / 2)
        # last rectangle
        last_dia_rect_h = screen_h - h - last_rect_h
        self.rectangles.add(f"{left}, {last_dia_rect_h}, {w}, {h}")
        # another side
        # first rectangle
        left = screen_w - w - last_rect_w
        top = vertical_delta
        self.rectangles.add(f"{left}, {top}, {w}, {h}")
        # middle rectangle
        left -= horizontal_delta
        top = dia_top
        while left > w:
            self.rectangles.add(f"{left}, {top}, {w}, {h}")
            left -= horizontal_delta
            top += int(h / 2)
        # last rectangle
        left = horizontal_delta
        self.rectangles.add(f"{left}, {last_dia_rect_h}, {w}, {h}")
        # for r in self.rectangles:
        #     print(str(r))
        # 初始化小部件
        self.__initWidget()
        # 画矩形
        self.drawRectangles()

    def drawRectangles(self):
        self.totalSet.clear()
        self.doneSet.clear()
        # print('rect count: ' + str(len(self.rectangles)))
        for rect_str in self.rectangles:
            rect_list = rect_str.split(",")
            rect = QGraphicsRectItem(
                QRectF(float(rect_list[0]), float(rect_list[1]), float(rect_list[2]), float(rect_list[3])))
            rect.setPen(QPen(Qt.blue))
            # 加入场景
            self.graphicsScene.addItem(rect)
            self.totalSet.add(rect)

    def mouseMoveEvent(self, evt):
        QGraphicsView.mouseMoveEvent(self, evt)
        self.item = self.get_rect_item_at(evt)
        # 返回值：图元地址
        # 参数1 场景点坐标
        # 参数2 ？？？？
        if self.item != None:
            try:
                self.item.setBrush(QBrush(Qt.green))
                self.doneSet.add(self.item)
                # print(len(self.doneSet), len(self.totalSet))
                # if (self.totalSet & self.doneSet) == self.totalSet:
                if len(self.totalSet ^ self.doneSet) <= 0:
                    # print(self.totalSet)
                    # print(self.doneSet)
                    self.pixmapPass.setVisible(True)
                    self.myConfig.passTestItems.add('TpDrawLine')
            except Exception as e:
                pass
        # 画黑点
        pt = evt.pos()  # 获取鼠标坐标--view坐标
        lineItem = QGraphicsLineItem()
        pen = QPen()  # 建立画笔
        pen.setWidth(int(4 / self.myConfig.screenRatio))  # 设置画笔宽度
        lineItem.setPen(pen)
        lineItem.setLine(pt.x(), pt.y(), pt.x(), pt.y())
        self.graphicsScene.addItem(lineItem)
        self.coordinateText.setText(f"({pt.x()}, {pt.y()})")

    def get_rect_item_at(self, e):
        pos = e.pos()
        item = self.itemAt(pos)
        if isinstance(item, QGraphicsRectItem):
            return item
        return None

    def viewportEvent(self, event: QEvent):  # real signature unknown; restored from __doc__
        """ viewportEvent(self, QEvent) -> bool """
        # // 处理touch事件
        QGraphicsView.viewportEvent(self, event)
        # print('~' * 30)
        evType = event.type()
        if evType == QEvent.TouchBegin or evType == QEvent.TouchUpdate or evType == QEvent.TouchEnd:
            touchEvent = QTouchEvent(event)
            touchPoints = touchEvent.touchPoints()
            # print('touchPoints', touchPoints)
            if len(touchPoints) > 1:
                reply = QMessageBox.question(self, 'Message',
                                             "超过一根手指触摸屏幕，确认退出触摸测试？",
                                             QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
                if reply == QMessageBox.Yes:
                    self.close()
                elif reply == QMessageBox.No:
                    event.accept()
            # newEvent = QMouseEvent(QEvent.MouseButtonPress, QPointF(0, 0), Qt.LeftButton)
            # self.mousePressEvent(newEvent)
            self.releaseMouse()
        return False


if __name__ == '__main__':
    QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
    app = QApplication(sys.argv)
    w = TpDrawLineWindow()
    w.show()
    # w.showFullScreen()
    sys.exit(app.exec_())
